﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Events.cs" company="3po.ru">
//   Author: Alexander Ulitin [support@3po.ru]
//   
//   This file is part of Conusic.
//   
//   Conusic is free software: you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
//   
//   Conusic is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//   
//   You should have received a copy of the GNU General Public License
//   along with Conusic.  If not, see http://www.gnu.org/licenses/.
// </copyright>
// <summary>
//   The image editor.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Imager
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.IO;
    using System.Windows.Forms;

    using Conusic;

    /// <summary>
    /// The image editor.
    /// </summary>
    public partial class ImageEditor
    {
        #region Methods

        /// <summary>
        /// The image editor double click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void ImageEditorDoubleClick(object sender, EventArgs e)
        {
            if (this.selectedComponent is TextComponent)
            {
                (this.selectedComponent as TextComponent).StartEditText();
            }
            else if (this.selectedComponent == null)
            {
                var dialog = new OpenFileDialog();
                dialog.Multiselect = false;

                // dialog.InitialDirectory = Config.Instance.GetStringParam("DefaultDialogDir");
                dialog.Filter =
                    @"Изображения (*.bmp;*.jpg;*.gif;*.png)|*.bmp;*.jpg;*.gif;*.jpeg;*.png|Все файлы (*.*)|*.*";
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    // Config.Instance.SetStringParam("DefaultDialogDir", Path.GetDirectoryName(dialog.FileName));
                    this.ImportImage(dialog.FileName, (e as MouseEventArgs).Location);
                }
            }
        }

        /// <summary>
        /// The image editor drag drop.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void ImageEditorDragDrop(object sender, DragEventArgs e)
        {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            string file = files[0];

            var point = new Point(e.X, e.Y);
            this.ImportImage(file, point);

            this.Invalidate();
        }

        /// <summary>
        /// The image editor drag enter.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void ImageEditorDragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.All;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        /// <summary>
        /// The image editor key down.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void ImageEditorKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                this.drawingComponents.Remove(this.selectedComponent);
                this.selectedComponent = null;
                this.markers.Clear();
            }

            this.Invalidate();
        }

        /// <summary>
        /// The image editor mouse down.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void ImageEditorMouseDown(object sender, MouseEventArgs e)
        {
            this.dragComponent = this.GetComponentInPosition(e.X, e.Y);

            if (this.dragComponent is Marker)
            {
                this.dragtype = DragTypes.resize;
            }
            else
            {
                this.selectedComponent = this.dragComponent;

                if (this.drawingComponents.Remove(this.selectedComponent))
                {
                    this.drawingComponents.Insert(0, this.selectedComponent);
                }

                this.dragtype = DragTypes.move;
                if (this.dragComponent != null)
                {
                    this.dragStartPointInFigure = new Point(
                        e.X - this.dragComponent.border.X, e.Y - this.dragComponent.border.Y);
                }
            }

            if (this.markers != null)
            {
                this.markers.Clear();
            }
            else
            {
                this.markers = new List<Marker>();
            }

            if (this.selectedComponent != null && this.selectedComponent.Resizeble)
            {
                this.markers.Add(new Marker(this.selectedComponent, Marker.MarkersType.TopLeft));
                this.markers.Add(new Marker(this.selectedComponent, Marker.MarkersType.TopRight));
                this.markers.Add(new Marker(this.selectedComponent, Marker.MarkersType.BottomLeft));
                this.markers.Add(new Marker(this.selectedComponent, Marker.MarkersType.BottomRight));
            }

            if (this.selectedComponent is TextComponent)
            {
                this.SetUserFont((this.selectedComponent as TextComponent).Font);
            }

            this.Invalidate();
        }

        /// <summary>
        /// The image editor mouse move.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        /// <exception cref="Exception">
        /// </exception>
        private void ImageEditorMouseMove(object sender, MouseEventArgs e)
        {
            if (this.dragComponent != null)
            {
                if (this.dragtype == DragTypes.move)
                {
                    this.dragComponent.Move(e.X - this.dragStartPointInFigure.X, e.Y - this.dragStartPointInFigure.Y);
                }
                else if (this.dragtype == DragTypes.resize)
                {
                    this.dragComponent.Move(e.X, e.Y);
                }
            }
            else
            {
                var figure = this.GetComponentInPosition(e.X, e.Y);
                if (figure == null)
                {
                    this.Cursor = Cursors.Arrow;
                }
                else if (figure is Marker)
                {
                    switch ((figure as Marker).markerType)
                    {
                        case Marker.MarkersType.TopLeft:
                            this.Cursor = Cursors.PanNW;
                            break;
                        case Marker.MarkersType.TopRight:
                            this.Cursor = Cursors.PanNE;
                            break;
                        case Marker.MarkersType.BottomLeft:
                            this.Cursor = Cursors.PanSW;
                            break;
                        case Marker.MarkersType.BottomRight:
                            this.Cursor = Cursors.PanSE;
                            break;
                        default:
                            throw new Exception("Invalid value for MarkersType");
                    }
                }
                else
                {
                    this.Cursor = Cursors.Hand;
                }
            }

            this.Invalidate();
        }

        /// <summary>
        /// The image editor mouse up.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void ImageEditorMouseUp(object sender, MouseEventArgs e)
        {
            this.dragComponent = null;
            this.Invalidate();
        }

        /// <summary>
        /// The image editor size changed.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void ImageEditorSizeChanged(object sender, EventArgs e)
        {
            Rectangle re = this.GetGraffityPart(this.CurrentSize);
            Rectangle rn = this.GetGraffityPart();

            // move all componetns to center;
            foreach (var a in this.drawingComponents)
            {
                a.border.X += rn.X - re.X;
                a.border.Y += rn.Y - re.Y;
            }

            this.CurrentSize = this.Size;
        }

        /// <summary>
        /// The import image.
        /// </summary>
        /// <param name="file">
        /// The file.
        /// </param>
        /// <param name="point">
        /// The point.
        /// </param>
        /// <exception cref="Exception">
        /// </exception>
        private void ImportImage(string file, Point point)
        {
            if (!string.IsNullOrEmpty(file))
            {
                try
                {
                    Image img = new Bitmap(file);

                    // Prevent using images internal thumbnail
                    img.RotateFlip(RotateFlipType.Rotate180FlipNone);
                    img.RotateFlip(RotateFlipType.Rotate180FlipNone);

                    if (img.Width > this.Width)
                    {
                        var img2 = img.GetThumbnailImage(
                            this.Width, img.Height * this.Width / img.Width, null, IntPtr.Zero);
                        img.Dispose();
                        img = img2;
                    }

                    if (this.drawingComponents.Count == 0)
                    {
                        Rectangle graffiti = this.GetGraffityPart();
                        this.drawingComponents.Insert(
                            0, new ImageComponent(img, this.graffityPart.X, this.graffityPart.Y, 586, 293));
                    }
                    else
                    {
                        this.drawingComponents.Insert(
                            0,
                            new ImageComponent(
                                img, this.PointToClient(point).X, this.PointToClient(point).Y, img.Width, img.Height));
                    }
                }
                catch (Exception ea)
                {
                    throw ea;
                }
            }
        }

        #endregion
    }
}